﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using System.Collections;

namespace System
{
    /// <summary>
    /// 反射帮助类
    /// </summary>
    public class CReflection
    {
        //[ThreadStatic]
        static Hashtable attributes = new Hashtable();
        static Dictionary<string, PropertyInfo> propertyInfos = new Dictionary<string, PropertyInfo>();
        static Dictionary<string, ModelFieldAttribute> modelFieldAttributes = new Dictionary<string, ModelFieldAttribute>();
        static Dictionary<string, MemberInfo> methodInfos = new Dictionary<string, MemberInfo>();
        static Dictionary<string, PropertyInfo[]> proInfos = new Dictionary<string, PropertyInfo[]>();

        /// <summary>
        /// 获取对象属性
        /// </summary>
        /// <param name="type">对象类型</param>
        /// <param name="proName">属性名</param>
        /// <returns>返回对象属性</returns>
        public static PropertyInfo GetPropertyInfo(Type type, string proName)
        {
            if (type == null) return null;

            PropertyInfo result = null;

            lock (propertyInfos)
            {
                string key = type.FullName + "." + proName;

                if (propertyInfos.ContainsKey(key))
                {
                    result = (PropertyInfo)propertyInfos[key];
                }
                else
                {
                    result = type.GetProperty(proName, StaticData.BindingFlags);
                    propertyInfos.Add(key, result);
                }
            }

            return result;
        }

        /// <summary>
        /// 获取对象属性
        /// </summary>
        /// <param name="model">待处理对象</param>
        /// <param name="methodName">属性名</param>
        /// <returns>结果</returns>
        public static MethodInfo GetModelethodInfo(object model, string methodName)
        {
            if (model == null)
                return null;
            return GetModelethodInfo(model.GetType(), methodName);
        }

        /// <summary>
        /// 获取对象属性
        /// </summary>
        /// <param name="type">对象类型</param>
        /// <param name="methodName">属性名</param>
        /// <returns>结果</returns>
        public static MethodInfo GetModelethodInfo(Type type, string methodName)
        {
            if (type == null) return null;
            MethodInfo result = null;

            lock (methodInfos)
            {
                string key = type.FullName + "." + methodName;

                if (methodInfos.ContainsKey(key))
                {
                    result = (MethodInfo)methodInfos[key];
                }
                else
                {
                    result = type.GetMethod(methodName, StaticData.BindingFlags);
                    methodInfos.Add(key, result);
                }
            }

            return result;
        }

        /// <summary>
        /// 获取属性
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="model">待处理对象</param>
        /// <param name="proName">属性名</param>
        /// <returns>结果</returns>
        public static PropertyInfo GetPropertyInfo<T>(T model, string proName) where T:BaseModel,new()
        {
            if (model == null) return null;
            return GetPropertyInfo(model.GetType(), proName);
        }

        /// <summary>
        /// 获取属性
        /// </summary>
        /// <param name="model">待处理对象</param>
        /// <param name="proName">属性名</param>
        /// <returns>结果</returns>
        public static PropertyInfo GetPropertyInfo(object model, string proName)
        {
            if (model == null) return null;
            return GetPropertyInfo(model.GetType(), proName);
        }

        /// <summary>
        /// 获取对象ModelAttribute
        /// </summary>
        /// <param name="modelType">对象类型</param>
        /// <returns>结果</returns>
        public static  ModelAttribute GetAttribute(Type modelType)
        {
            ModelAttribute result = null;
            ModelAttribute[] results = modelType.GetCustomAttributes(typeof(ModelAttribute), true) as ModelAttribute[];
            if (results != null && results.Length > 0)
            {
                result = results[0];
            }
            return result;
        }

        /// <summary>
        /// 获取属性Attribute
        /// </summary>
        /// <param name="proInfo">属性</param>
        /// <param name="attributeType">Attribute类型</param>
        /// <returns>Attribute</returns>
        public static Attribute GetAttribute(PropertyInfo proInfo, Type attributeType)
        {
            if (proInfo == null || attributeType == null)
                return null;
            Attribute result = null;

            lock (attributes)
            {
                string key = proInfo.DeclaringType.FullName + "." + proInfo.Name + "." + attributeType.FullName;

                if (attributes.ContainsKey(key))
                {
                    result = (Attribute)attributes[key];
                }
                else
                {
                    result = Attribute.GetCustomAttribute(proInfo, attributeType);
                    attributes.Add(key, result);
                }
            }
            return result;
        }

        /// <summary>
        /// 获取属性ModelFieldAttribute
        /// </summary>
        /// <param name="proInfo">属性</param>
        /// <returns>结果</returns>
        public static ModelFieldAttribute GetModelFieldAttribute(MemberInfo proInfo)
        {
            if (proInfo == null)
                return null;
            ModelFieldAttribute result = null;

            lock (modelFieldAttributes)
            {
                string key = proInfo.DeclaringType.FullName + "." + proInfo.Name;

                if (modelFieldAttributes.ContainsKey(key))
                {
                    result = (ModelFieldAttribute)modelFieldAttributes[key];
                }
                else
                {
                    result = (ModelFieldAttribute)Attribute.GetCustomAttribute(proInfo, typeof(ModelFieldAttribute));
                    modelFieldAttributes.Add(key, result);
                }
            }
            return result;
        }

        /// <summary>
        /// 获取属性ModelFieldAttribute
        /// </summary>
        /// <param name="model">待处理对象</param>
        /// <param name="proName">属性名</param>
        /// <returns>结果</returns>
        public static ModelFieldAttribute GetModelFieldAttribute(object model, string proName)
        {
            if (model == null) return null;
            PropertyInfo info = GetPropertyInfo(model, proName);
            return GetModelFieldAttribute(info);
        }

        /// <summary>
        /// 获取对象全部属性
        /// </summary>
        /// <param name="type">对象类型</param>
        /// <returns>结果</returns>
        public static PropertyInfo[] GetPropertyInfos(Type type)
        {
            if (type == null) return null;

            PropertyInfo[] result = null;

            lock (proInfos)
            {
                string key = type.FullName;
                if (proInfos.ContainsKey(key))
                {
                    result = (PropertyInfo[])proInfos[key];
                }
                else
                {
                    result = type.GetProperties();
                    proInfos.Add(key, result);
                }
            }

            return result;
        }
    }
}
